import { ref,onMounted,reactive, toRaw  } from "vue"
import { getTabsContent,like,dislike } from "@/api/home"
import { showNotify } from 'vant'
import { localStorage } from '@/utils/local-storage'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { showToast} from 'vant'
import { STORAGE_TOKEN_KEY } from '@/stores/mutation-type'
import useCounterStore from "@/stores/modules/counter"
const counterStore = useCounterStore()
type PARAMS = {
  query:String;
  conversation_id:String;
  history_len:Number;
  user_name:String;
  history:Array<[]>;
  stream:Boolean;
  model_name:String;
  temperature:Number;
  max_tokens:Number;
  prompt_name:String;
  knowledge_base_name:String;
}
type VANTABLIST= {
  title:String;
  channel:String;
  content:String;
  api:String;
  knowledge_base_name:String;
  apiName:string;
}
type CONTENTLIST = {
  time:string,
  qu:string,
  loading:Boolean | Number,
  isStop:Boolean,
  mdText:string,
  tap:Boolean,
  noTap:Boolean,
  docs?:[{
    content:string;
    filename:string;
    index:string;
    url:string;
  }]
}
 const vanTabList = reactive<Array<VANTABLIST>>([
  {
    title:'标准规范',
    channel:'standard',
    knowledge_base_name:'标准规范321',
    api:'/chat/knowledge_base_chat',
    apiName:'answer',
    content:'嗨~我是天津设计院标准规范的查询助手，请输入您所提问内容或关键词。',
  },
  {
    title:'规章制度',
    channel:'rules',
    knowledge_base_name:'规范制度',
    api:'/chat/knowledge_base_chat',
    apiName:'text',
    content:'嗨~我是天津设计院规章制度的查询助手，请输入您所提问内容或关键词。'
  },
  {
    title:'对话问答',
    channel:'chat',
    api:'/chat/chat',
    knowledge_base_name:'',
    apiName:'text',
    content:'嗨~我是天津设计院对话问答助手，请输入您所提问内容或关键词。',
  },

  {
    title:'智能问数',
    api:'/chat/chat_platform',
    channel:'information',
    knowledge_base_name:'',
    apiName:'text',
    content:'嗨~我是天津设计院智能问答的查询助手，请输入您所提问内容或关键词。',
  },
  {
    title:'ERP指南',
    channel:'ERP',
    apiName:'answer',
    knowledge_base_name:'ERP',
    api:'/chat/knowledge_base_chat',
    content:'嗨~我是天津设计院ERP指南的查询助手，请输入您所提问内容或关键词。',
  }
])
const vanTabListIndex = ref<Number>(0)
 const inputValue = ref<string>('')
 const tabList = ref([])
 const active = ref(null)
 const state = reactive({})
 const vaninput = ref<HTMLInputElement|null>(null);
 const scrollInto = ref(null)
 // 请求
 const ctrl = ref()
 const eventSource = ref()
// 状态组件
 const flgStop = ref('停止生成')
 const flgStatus=ref(false)
 const contentList = ref<CONTENTLIST[]>([
  // {
  //   time:'',
  //   qu:'',
  //   loading:false,
  //   mdText: '',
  // }
])
 const onGetToken = () =>{
  // getToken().then(res=>{
  //   setToken({accessToken:res.data,username:'admin'})
  // })
      // @ts-ignore
      // const dom = document.getElementsByClassName('.card_box')

      // autoScrollButtom()
      
      // @ts-ignore
      // 
  // @ts-ignore
  // main_scroll.value[1].scrollTop = main_scroll.value[1].scrollHeight
  // @ts-ignore scrollTop scrollHeight
  // div.scrollTop = div.scrollHeight
} 
const editMsg= (content?:string,value?:string | boolean):void=> {
   contentList.value.at(-1)[content] = value
}
const contentMsg = (val:String) =>{
  // 未处理的值
 
   const key = Object.keys(val)[0]
   const name = ['answer','docs','text'].find(x=>x===key)
   const newVal = val[name]
   contentList.value.at(-1).loading = val['end']
   if(name === 'docs'){
    contentList.value.at(-1).docs = newVal
    return 
   }
  contentList.value.at(-1).mdText += newVal
}

// autoScrollButtom
const autoScrollButtom = () =>{
  const dom = document.getElementById('card_box'+vanTabListIndex.value)
  // @ts-ignore
  dom.scrollIntoView({ behavior: 'smooth',block:'end' });
}
// 发送流请求
const AjaxSendMsg = (url?:string) =>{
  if(flgStatus.value) return 
  if(contentList.value.length <= 0) return 
  if(!inputValue.value) return 
  inputValue.value = ''
  // const host = "http://11.145.17.224:7861"  // 对话问答(text)  规范标准（answer） 智能问答(text)   Erp(answer)
  // const host1 = "http://11.145.18.125:7861" // 规章制度(text)
  // const host2 = 
  // 联网查询 /chat/chat_internet
    // @ts-ignore
  const vanTabItem =  vanTabList[toRaw(vanTabListIndex.value)]
  const HTTP =  `${ url?url:vanTabItem.api}`
    url = url || vanTabItem.api
  const user_name = localStorage.get('username')
  const knowledge_base_name = vanTabItem.knowledge_base_name
  //  @ts-ignore
  const query = contentList.value.at(-1).qu
  const params:PARAMS = {
    query,
    conversation_id: "",
    history_len: -1,
    history: [],
    stream: true,
    model_name: "chatglm3-6b",
    temperature: 0.7,
    max_tokens: 0,
    prompt_name: "default",
    user_name,
    knowledge_base_name
  }
  // class RetriableError extends Error { }
  class FatalError extends Error { }
   ctrl.value = new AbortController()
    eventSource.value = fetchEventSource(HTTP, {
    method: 'POST',
    // mode: 'no-cors',
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/json',
      'Authorization':localStorage.get( STORAGE_TOKEN_KEY)
  },
    body: JSON.stringify(params),
    signal: ctrl.value.signal,
    openWhenHidden: true,
  //   onopen:async (response)=> {
  //    const stream  =   response.body
  //    if (stream instanceof ReadableStream) {
  //     const reader = stream.getReader();
  //     // console.log(reader,'reader');
  //    }
  //     if (response.ok && response.headers.get('content-type') === 'EventStreamContentType') {
  //         return; // everything's good
  //     } else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
  //         // client-side errors are usually non-retriable:
  //         throw new FatalError();
  //     } else {
  //         throw new RetriableError();
  //     }
  // },
    onmessage:(msg)=> {
      // if the server emits an error message, throw an exception
      // so it gets handled by the onerror callback below:
      if (msg.event === 'FatalError') {
          ctrl.value.abort()
          throw new FatalError(msg.data);
      }
      const data = JSON.parse(msg.data)
      flgStatus.value = data.end !== 'true'
      // @ts-ignore
      contentMsg(data)
      autoScrollButtom()
    },
    onclose:()=> {
      ctrl.value.abort()
    },
    onerror(err) {
      const token = localStorage.get(STORAGE_TOKEN_KEY)
      if( String(err).startsWith('SyntaxError')) return 
      if(token){
        showNotify({
          type: 'danger',
          message: '登录已过期,请重新登陆',
        })
        localStorage.remove(STORAGE_TOKEN_KEY)
      }
      counterStore.isLoginChange(false)
      location.reload()
      
      if (err instanceof FatalError) {
        throw err; // rethrow to stop the operation
    } else {
        // do nothing to automatically retry. You can also
        // return a specific retry interval here.
    }
      ctrl.value.abort()
    },
  })
}
const addMsg = () =>{
  if(flgStatus.value){
    showToast({
      message: '当前对话进行中',
      position: 'bottom',
  });
  return 
  }
  if(!inputValue.value) return 
 const currentDate = new Date();
 const hours = currentDate.getHours();
 const minutes = currentDate.getMinutes();
 contentList.value.push({
   time:`${hours}:${minutes}`,
   qu:inputValue.value,
   loading:1,
   isStop:false,
   mdText:'',
   tap:false,
   noTap:false,
 })
 vaninput.value?.blur()
}
const onClickCardItem = (val:string) =>{
  inputValue.value = val
  addMsg()
  AjaxSendMsg()
}

export const useContent= ()=>{
    const linePhoneFlg = ref(true)
    const onLineClick  = () =>{
      linePhoneFlg.value = !linePhoneFlg.value
    }
    const submitClick = () =>{
      addMsg()
      AjaxSendMsg()
    }
    const onLuYinClick = () =>{
      console.log('录音');
    }
    const onChangeTabs = (name:string | number, title:string) =>{
      const data = {
        channel:name,
        maxcount:'-1'
      }
      vanTabListIndex.value = vanTabList.findIndex(x=>x.title === title)
      // 初始化页面状态
      // ctrl.abort()
       // @ts-ignore
      contentList.value=[]
      getTabsContent(data).then(res=>{
        // @ts-ignore
        tabList.value = res.questions
      }).catch(err=>{
        const token = localStorage.get(STORAGE_TOKEN_KEY)
        if(token){
          showNotify({
            type: 'danger',
            message: '登录已过期,请重新登陆',
          })
          localStorage.remove(STORAGE_TOKEN_KEY)
        }
        counterStore.isLoginChange(false)
      })
      // 接口地址：http://11.145.18.81:7861/samples
    }
  // 点赞
    const onChangeImgFlg = (flg) => {
     
      
      const username = localStorage.get('username')
       // @ts-ignore
      const model = vanTabList[vanTabListIndex.value].channel
      const question = contentList.value.at(-1)['qu']
      const  answer =  contentList.value.at(-1)['mdText']

      
      like({username,model,question,answer}).then(res=>{
        showToast({
          // @ts-ignore
          message: res,
          position: 'bottom',
      });
      flg.tap = true
      })
    }
  // 差评
    const onChangeImgFlg2 = (flg) => {
      const username = localStorage.get('username')
       // @ts-ignore
      const model = vanTabList[vanTabListIndex.value].channel
      const question = contentList.value.at(-1)['qu']
      const  answer =  contentList.value.at(-1)['mdText']
      dislike({username,model,question,answer,advice:'',}).then(res=>{
        showToast({
          // @ts-ignore
          message: res,
          position: 'bottom',
      });
      flg.noTap= true

      })
      
    }
    // 联网查询
    const onSearchImg = (val:string) => {
      inputValue.value = val
      addMsg()
      AjaxSendMsg('/chat/chat_internet')
     
    }
    // 重新生成
    const onRefushImg = (val:string) =>{
      onClickCardItem(val)
    }

    // 
    const onStopChange = () => {
      if(flgStop.value === '停止生成'){
        editMsg('isStop',true)
        ctrl.value.abort()
         flgStatus.value = false 
        // flgStop.value = '重新生成'
      }
      // if(flgStop.value === '重新生成'){
      //   flgStop.value = '停止生成'
      //   AjaxSendMsg()
      // }
    }
    onMounted(() => {
      
    });
    return {
      linePhoneFlg,
      onLineClick,
      onLuYinClick,
      onChangeTabs,
      submitClick,
      onChangeImgFlg,
      onChangeImgFlg2,
      onSearchImg,
      onStopChange,
      onRefushImg
      
    }
}
export {
  vanTabList,
  inputValue,
  vaninput,
  tabList,
  scrollInto,
  active,
  state,
  flgStop,
  flgStatus,
  contentList,
  onGetToken,
  onClickCardItem
}
